program class_inherit;

// 父类 Animal
class Animal;
    // public 是默认的访问权限(无需显式声明), 在任何地方都可以访问
    // protected 限定只能被本类和子类访问
    // local 只能被本类访问
    protected string name;
    protected int age;
    
    function new(string name = "Unknown", int age = 0);
        this.name = name;  // 使用this关键字引用当前实例的成员
        this.age = age;
    endfunction
    
    virtual function void display();
          $display("Animal: name=%s, age=%0d", name, age);
    endfunction
    
    virtual function string make_sound();
          return "Animal sound";
    endfunction
endclass

// 子类 Dog: 继承自 Animal
class Dog extends Animal;
    local string breed; // 只能被本类访问
    
    function new(string name = "Dog", int age = 0, string breed = "Unknown");
        // super 关键字用于从派生类中引用父类的属性。
        // 当派生类的属性被重写且无法直接访问时，必须使用 super。
        super.new(name, age);  // 调用父类构造函数
        this.breed = breed;    // 初始化子类特有的成员
    endfunction
    
    virtual function void display();
        $display("Dog: name=%s, age=%0d, breed=%s", name, age, breed);
    endfunction
    
    virtual function string make_sound();
        return "Woof!";
    endfunction

    function void wag_tail();
        $display("%s is wagging tail", name);
    endfunction
endclass

initial begin
    // !!! 变量声明必须位于过程块（如 initial/always）的开头，即在任何可执行语句之前。
    Animal animal = new("Generic Animal", 5);
    Dog dog = new("Buddy", 3, "Golden Retriever");
    Animal animals[2];

    // 调用方法
    animal.display();
    $display("Sound: %s\n", animal.make_sound());
    dog.display();
    $display("Sound: %s", dog.make_sound());
    dog.wag_tail();
    $display("");


    // 多态示例
    $display("\nPolymorphism: ");
    
    animals[0] = animal;
    animals[1] = dog;

    foreach (animals[i]) begin
        animals[i].display();
        $display("Sound: %s", animals[i].make_sound());
    end
end

endprogram
